using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Ruminate.GUI.Framework;
using Ruminate.Utils;

namespace Ruminate.GUI.Content {

    public class RadioButton : Element {

        /*####################################################################*/
        /*                               Grouping                             */
        /*####################################################################*/
        #region Grouping
        private static readonly Dictionary<string, List<RadioButton>> Groups = 
            new Dictionary<string, List<RadioButton>>();

        private void AddRadioButton(string group, RadioButton button) {

            if (!Groups.ContainsKey(group)) { Groups.Add(group, new List<RadioButton>()); }

            Groups[group].Add(button);
        }
        #endregion


        /*####################################################################*/
        /*                               Variables                            */
        /*####################################################################*/

        /* ## Local Variables ## */
        private IconRenderer _iconRenderer;
        private TextRenderer _textRenderer;       
        private Texture2D _checked, _checkedHover, _unchecked, _uncheckedHover;        
        private readonly string _group;

        /* ## Exposed Variables ## */
        public ElementEvent OnCheck { get; set; }
        public ElementEvent OnUnCheck { get; set; }

        public string Label { get; set; }

        private bool _innerIsChecked;
        public bool IsChecked {
            get { return _innerIsChecked; }
            private set {

                if (!value) { throw new ArgumentException("IsChecked can only be set to true"); }

                _innerIsChecked = true;
                if (OnCheck != null) {
                    OnCheck(this);
                }

                foreach (var radioButton in Groups[_group]) {
                    if (radioButton == this) { continue; }

                    radioButton._innerIsChecked = false;
                    if (radioButton.OnUnCheck != null) {
                        radioButton.OnUnCheck(radioButton);
                    }
                }
            }
        }                

        /*####################################################################*/
        /*                           Initialization                           */
        /*####################################################################*/

        public RadioButton(int x, int y, string group, string label) 
            : base(new Offset(x, y, 0, 0)) {

            Label = label;
            _innerIsChecked = false;

            _group = group;
            AddRadioButton(group, this);
        }

        /*####################################################################*/
        /*                                Resized                             */
        /*####################################################################*/

        /// <inheritdoc/>
        protected internal override void Init() {

            _iconRenderer = (IconRenderer)InstanceData.DefaultRenderers["Radio"];
            _textRenderer = (TextRenderer)InstanceData.DefaultRenderers["TextRenderer"];

            var size = _textRenderer.Font.MeasureString(Label);
            LocationComponent.Size = new Vector2(
                size.X + 2 + _iconRenderer.IconSize.X,
                _iconRenderer.IconSize.Y);
        }

        protected internal override void Render() {

            var size = LocationComponent.Size.ToPoint();

            _unchecked = _iconRenderer.Render(size, 0, _textRenderer, Label);
            _uncheckedHover = _iconRenderer.Render(size, 2, _textRenderer, Label);

            _checked = _iconRenderer.Render(size, 1, _textRenderer, Label);
            _checkedHover = _iconRenderer.Render(size, 3, _textRenderer, Label);
        }

        protected internal override Rectangle ChildRenderArea() {

            return LocationComponent.RenderBounds;
        }

        /*####################################################################*/
        /*                                Events                              */
        /*####################################################################*/

        protected internal override void MouseClick(MouseEventArgs e) {

            IsChecked = true;
        }

        /*####################################################################*/
        /*                                Logic                               */
        /*####################################################################*/                

        /// <inheritdoc/>
        protected internal override void Update() { }

        /// <inheritdoc/>
        protected internal override void Draw() {

            if (IsChecked) {
                SpriteBatch.Draw(
                    IsHover ? _checkedHover : _checked,
                    LocationComponent.RenderLocation, 
                    Color.White);
            } else {
                SpriteBatch.Draw(
                    IsHover ? _uncheckedHover : _unchecked,
                    LocationComponent.RenderLocation,
                    Color.White);
            }
        }        
    }
}